﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;

namespace Project.T4Code
{
    public abstract class BaseSqlBuilder
    {
        public BaseSqlBuilder(string tableName, PropertyInfo[] properties, string provider)
        {
            this.TableName = tableName;
            this.Properties = properties;
            this.ProviderFactoryString = provider;
            Init();
        }

        //internal readonly string ProviderFactoryString = ConfigurationManager.ConnectionStrings["ConnectionString"].ProviderName;
        /// <summary>
        /// 用来判断是oracle还是sqlserver
        /// </summary>
        public string ProviderFactoryString { get; set; }

        /// <summary>
        /// 类名
        /// </summary>
        public string TableName { get; set; }
        /// <summary>
        /// 属性名
        /// </summary>
        public PropertyInfo[] Properties { get; set; }
        /// <summary>
        /// 所有的表信息 key是表名 value是相应的type
        /// </summary>
        internal Dictionary<string, Type> tableDict = new Dictionary<string, Type>();
        /// <summary>
        /// 所有的枚举
        /// </summary>
        internal List<string> enumList = new List<string>();

        /// <summary>
        /// 初始化方法，反射出所有的类和所有的枚举
        /// </summary>
        public void Init()
        {
            GetAssemblyModel();
            GetAssemblyEnum();
        }
        /// <summary>
        /// 获取所有的类
        /// </summary>
        public void GetAssemblyModel()
        {
            //load方法里可以直接写程序集名字
            //反射出Model中所有的类
            Assembly modelAssembly = Assembly.Load("Project.Model");
            //遍历反射出的Model，放到Dict中
            foreach (var type in modelAssembly.GetTypes())
            {
                if (type.Name != TableName)
                {
                    //key是表名 value是相应的type
                    tableDict.Add(type.Name, type);
                }
            }
        }
        /// <summary>
        /// 获取所有的枚举
        /// </summary>
        public void GetAssemblyEnum()
        {
            //反射出所有的枚举
            Assembly commonAssembly = Assembly.Load("Project.Common");
            //遍历反射出的枚举，放到枚举集合里
            foreach (var type in commonAssembly.GetTypes())
            {
                if (type.BaseType != null && type.BaseType.Name == "Enum")
                {
                    enumList.Add(type.Name);
                }
            }
        }

        /// <summary>
        /// 获取相应的字符串
        /// </summary>
        /// <returns></returns>
        public abstract string GetSqlStr();

        /// <summary>
        /// 第一次获取字符串
        /// </summary>
        /// <param name="propertyName">属性参数</param>
        /// <param name="tableName">表名，查询的时候需要用到</param>
        /// <param name="nowLength">循环到的第几个参数</param>
        /// <param name="length">总的参数个数</param>
        /// <param name="isKey">是否为主键，默认不是主键</param>
        /// <param name="isContent">是否含有包含类</param>
        /// <returns></returns>
        public abstract string GetStringFirst(string propertyName, string tableName, int nowLength,
                                              int length, bool isContent = false, bool isKey = false,
                                              bool isEnum = false);

        #region 取消此方法将来或许会用到
        ///// <summary>
        ///// 第二次获取字符串
        ///// </summary>
        ///// <param name="model">字符串模版</param>
        ///// <param name="propertyName">参数</param>
        ///// <param name="isContent">是否包含类</param>
        ///// <returns></returns>
        //public virtual string GetStringSecond(string model, string propertyName, bool isContent = false)
        //{
        //    string result = "";
        //    //判断是否有包含类，有包含类将参数名后面加上Id
        //    if (isContent)
        //    {
        //        result = string.Format(model, propertyName + "Id");
        //    }
        //    else
        //    {
        //        result = string.Format(model, propertyName);
        //    }
        //    return result;
        //} 
        #endregion

        public virtual string GetConQueryStr(string tableName, PropertyInfo[] properties)
        {
            return "";
        }
    }
}